/****************************************************************************
 *
 *  ALi (Shanghai) Corporation, All Rights Reserved. 2007 Copyright (C)
 *
 *  File: mp_subtitle_osd.c
 *
 *  Description: This file describes subtitle osd operations.
 *
 *  History:
 *      Date        	Author      	Version  		Comment
 *      ====        	======      =======  	=======
 *  1.  2009.5.29  Martin_Xia  	0.0.1  		
 *
 ****************************************************************************/

#include <types.h>
#include <retcode.h>
#include <api/libc/printf.h>

#include <api/libc/string.h>
#include <osal/osal.h>
#include <hld/osd/osddrv.h>
#include <hld/hld_dev.h>
#include <hld/dis/vpo.h>
#include <api/libosd/osd_lib.h>
#include <api/libosd/osd_common.h>


#include <api/libmp/mp_subtitle_api.h>

#include "mp_subtitle_osd.h"

#include "copper_common/system_data.h" 
#include "osd_rsc.h"

/**********************Global  Variables***********************************/
//define the Global  Variables
const unsigned char mp_subtitle_pallette_256[4*256] = {
				/*front*/
				0x10, 0x80, 0x80, 0x0f,	//black
				0x50, 0x5b, 0xec, 0x0f,	//red
				0x8f, 0x37, 0x24, 0x0f,	//green
				0xd0, 0x12, 0x90, 0x0f,	//yellow
				0x27, 0xec, 0x6e, 0x0f,	//blue
				0x68, 0xc7, 0xda, 0x0f,	//magenta
				0xa7, 0xa3, 0x12, 0x0f,	//cyan
				0xea, 0x7f, 0x7f, 0x0f,	//white
				/*back*/
				0xea, 0x7f, 0x7f, 0x0f,	//white 
				0x50, 0x5b, 0xec, 0x0f,	//red
				0x8f, 0x37, 0x24, 0x0f,	//green
				0xd0, 0x12, 0x90, 0x0f,	//yellow
				0x27, 0xec, 0x6e, 0x0f,	//blue
				0x68, 0xc7, 0xda, 0x0f,	//magenta
				0xa7, 0xa3, 0x12, 0x0f,	//cyan
				0x10, 0x80, 0x80, 0x0f,	//black 

				0, 0, 0, 0,	//transparent
};

//for persian subtitle 20130618
#ifdef PERSIAN_SUPPORT
UINT16 str_keep[1024];
UINT16 str_cnt;
#endif

/**************************Static  Function Declare***********************************/
//static BOOL mp_subtitle_scale_no_bl(HANDLE osd_dev, UINT16 screen_width);
static void mp_subtitle_osd_clean_screen(MpSubtitleOsd *subtitle_osd);
static void mp_subtitle_osd_change_pallette(MpSubtitleOsd *subtitle_osd, unsigned char* pallette);
static void mp_subtitle_osd_draw_string(MpSubtitleOsd *subtitle_osd, unsigned short x, unsigned short y, unsigned char fg_color, unsigned short *string);
static void mp_subtitle_osd_draw_image(MpSubtitleOsd *subtitle_osd, unsigned short x, unsigned short y, unsigned short width, unsigned short height,unsigned char *image);
static void mp_subtitle_osd_get_rects_cross(const struct OSDRect *backR,const struct OSDRect *forgR, struct OSDRect* relativR);
static BOOL mp_subtitle_osd_bitmap_format_transfer(BitMap_t* bmpDest,BitMap_t* bmpSrc,UINT32 transColor,UINT32 foreColor);
static void mp_subtitle_osd_icon_char_data2bitmap(FONTICONPROP* pObjAttr,UINT8* pDtaBitmap,BitMap_t* bmp, ID_RSC RscLibId);
static void mp_subtitle_osd_draw_bmp(MpSubtitleOsd *subtitle_osd, UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag);
//static void mp_subtitle_osd_draw_bmp(UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag);
static void mp_subtitle_osd_draw_char(MpSubtitleOsd *subtitle_osd, unsigned short x, unsigned short y, unsigned char fg_color, unsigned short character);
static void mp_subtitle_osd_draw_char2(MpSubtitleOsd *subtitle_osd, unsigned char *char_addr,OBJECTINFO *object_info, struct OSDRect *r, ID_RSC resource_id, unsigned char fg_color);
#ifdef MP_SUBTITLE_SETTING_SUPPORT
static void mp_subtitle_osd_draw_bmp3(MpSubtitleOsd *subtitle_osd, UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag, UINT32 dwBgColorFlag);
static void mp_subtitle_osd_draw_char3(MpSubtitleOsd *subtitle_osd, unsigned char *char_addr,OBJECTINFO *object_info, struct OSDRect *r, ID_RSC resource_id, unsigned char fg_color, unsigned char bg_color);
#endif



#if 0
#endif
/****************************API  Function ***********************************/
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_create
//
// Description:
//	This function is sample callback function. The subtitle APIs will call this callback function to create a subtitle osd region. 
//    Customer who has different osd functions should implement it by yourself.
//
// Arguments:
//	subtitle_osd - Pointer to pointer a struct contains osd infomation
//	
// Return Value:
//	1 - Success
//	-1 - Failed
//
/////////////////////////////////////////////////////////////////////////////
int mp_subtitle_osd_create(MpSubtitleOsd **psubtitle_osd)
{
	struct OSDPara							osd_open_para;
	struct OSDRect							osd_open_rect;
	struct OSDRect							r;
	enum TVSystem							tv_sys;
	enum OSDSys							eOSDSys;
	MpSubtitleOsd								*subtitle_osd;

	MP_SUB_DEBUG("====>>mp_subtitle_osd_create()\n");


	if (!psubtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_create: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_create()\n");
		return -1;
	}


	subtitle_osd = (MpSubtitleOsd *)MALLOC(sizeof(MpSubtitleOsd));
	if (!subtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_create: Malloc failed!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_create()\n");
		return -1;
	}

	MEMSET(subtitle_osd, 0, sizeof(MpSubtitleOsd));

	subtitle_osd->osd_dev = dev_get_by_id(HLD_DEV_TYPE_OSD, 1);
	if (subtitle_osd->osd_dev == NULL)
	{
		FREE(subtitle_osd);
		MP_SUB_DEBUG("mp_subtitle_osd_create: Get osd_dev failed!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_create()\n");
		return -1;
	}
		

	OSDDrv_ShowOnOff((HANDLE)subtitle_osd->osd_dev, OSDDRV_OFF);


	osd_open_para.eMode= OSD_256_COLOR;
	osd_open_para.uGAlphaEnable= FALSE;	
	osd_open_para.uGAlpha= 0x0f;
	osd_open_para.uPalletteSel = 0;

	OSDDrv_Close((HANDLE)subtitle_osd->osd_dev);
	OSDDrv_Open((HANDLE)subtitle_osd->osd_dev, &osd_open_para);
	osal_task_sleep(20);


	osd_open_rect.uLeft = 0;//MP_SUBTITLE_OSD_STARTCOL;
	osd_open_rect.uWidth = MP_SUBTITLE_OSD_WIDTH;
	osd_open_rect.uTop = 0;//MP_SUBTITLE_OSD_STARTROW;
	osd_open_rect.uHeight = MP_SUBTITLE_OSD_HEIGHT;

	subtitle_osd->region = 0;
	OSDDrv_CreateRegion((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &(osd_open_rect), NULL);	
	OSDDrv_SetPallette((HANDLE)subtitle_osd->osd_dev,(unsigned char*)(mp_subtitle_pallette_256), 256, OSDDRV_YCBCR);
    
	r.uLeft = 0;
	r.uTop = 0;
	r.uWidth =osd_open_rect.uWidth;
	r.uHeight =osd_open_rect.uHeight;
	OSDDrv_RegionFill((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &r, 16);

	vpo_ioctl((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS), VPO_IO_GET_OUT_MODE, (UINT32)(&tv_sys));
	if(tv_sys == NTSC||tv_sys == PAL_M||tv_sys == PAL_60||tv_sys == NTSC_443)
	{
		eOSDSys = OSD_NTSC;
	}
	else
	{
		eOSDSys = OSD_PAL;
	}
	OSDDrv_Scale((HANDLE)subtitle_osd->osd_dev, OSD_VSCALE_TTX_SUBT, (unsigned long)(&eOSDSys));
	//mp_subtitle_scale_no_bl((HANDLE)subtitle_osd->osd_dev, MP_SUBTITLE_OSD_WIDTH);

	OSDDrv_ShowOnOff((HANDLE)subtitle_osd->osd_dev, OSDDRV_ON);
	OSDDrv_RegionShow((HANDLE)subtitle_osd->osd_dev,subtitle_osd->region,TRUE);

	*psubtitle_osd = subtitle_osd;

	MP_SUB_DEBUG("<<====mp_subtitle_osd_create()\n");

	return 1;
}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_destroy
//
// Description:
//	This function is sample callback function. The subtitle APIs will call this callback function to delete a subtitle osd region. 
//    Customer who has different osd functions should implement it by yourself.
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	
// Return Value:
//	1 - Success
//	-1 - Failed
//
/////////////////////////////////////////////////////////////////////////////
int mp_subtitle_osd_destroy(MpSubtitleOsd *subtitle_osd)
{
	struct OSDRect							r;


	MP_SUB_DEBUG("====>>mp_subtitle_osd_destroy()\n");

	if (!subtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_destroy: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_destroy()\n");
		return -1;
	}

	r.uLeft = 0;
	r.uTop = 0;
	r.uWidth = MP_SUBTITLE_OSD_WIDTH;
	r.uHeight = MP_SUBTITLE_OSD_HEIGHT;

	OSDDrv_RegionFill((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &r, 16);


	OSDDrv_DeleteRegion((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region);


	//OSDDrv_Scale((HANDLE)osd_dev,OSD_VSCALE_OFF,(unsigned long)(&eOSDSys));
	OSDDrv_ShowOnOff((HANDLE)subtitle_osd->osd_dev, OSDDRV_OFF);

	FREE(subtitle_osd);

	MP_SUB_DEBUG("<<====mp_subtitle_osd_destroy()\n");

	return 1;
}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_clean_screen
//
// Description:
//	This function is sample callback function. The subtitle APIs will call this callback function to control  subtitle osd. 
//	It will use this callback to clean screen, change palette, draw string and draw image at now. 
//	Customer who has different osd functions should implement it by yourself.
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	control_code - Control code
//	parameters - Depends on control_code
//
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
long mp_subtitle_osd_control(MpSubtitleOsd *subtitle_osd, long control_code, long parameters)
{
	long					ret;


	MP_SUB_DEBUG("====>>mp_subtitle_osd_control()\n");

	ret = -1;
	switch (control_code)
	{
		case MP_SUBTITLE_CONTROL_CLEAN_SCREEN:
		{
			MP_SUB_DEBUG("mp_subtitle_osd_control: MP_SUBTITLE_CONTROL_CLEAN_SCREEN\n");
			mp_subtitle_osd_clean_screen(subtitle_osd);
			ret = 1;
			break;
		}

		case MP_SUBTITLE_CHANGE_PALLETE:
		{
			MP_SUB_DEBUG("mp_subtitle_osd_control: MP_SUBTITLE_CHANGE_PALLETE\n");
			mp_subtitle_osd_change_pallette(subtitle_osd, (unsigned char*)parameters);
			ret = 1;
			break;
		}

		case MP_SUBTITLE_DRAW_STRING:
		{
			MP_SUB_DEBUG("mp_subtitle_osd_control: MP_SUBTITLE_DRAW_STRING\n");
			MpSubtitleDrawStringParameters		*para;
			para = (MpSubtitleDrawStringParameters*) parameters;
			if (para)
			{
				//mp_subtitle_osd_draw_string(subtitle_osd, 100, 410, 7, para->string);
                mp_subtitle_osd_draw_string(subtitle_osd, para->x, 410, para->fg_color, para->string);
                ret = 1;
			}
			break;
		}

		case MP_SUBTITLE_DRAW_IMAGE:
		{
			MP_SUB_DEBUG("mp_subtitle_osd_control: MP_SUBTITLE_DRAW_IMAGE\n");
			MpSubtitleDrawImageParameters		*para;
			para = (MpSubtitleDrawImageParameters*) parameters;
			if (para)
			{
                if(para->y + para->height > 576)
                {
                    if (para->height > 576)
                        para->height = 576;
                    para->y = (576 - para->height) >> 1;
                    para->y &= ~1;
                }            
				mp_subtitle_osd_draw_image(subtitle_osd, para->x, para->y, para->width, para->height, para->image);
				ret = 1;
			}
			break;
		}

		default:
		{
			MP_SUB_DEBUG("mp_subtitle_osd_control: Unknown control code!\n");
			break;
		}
		
	}


	MP_SUB_DEBUG("<<====mp_subtitle_osd_control()\n");

	return ret;
}





#if 0
/**************************Internal Static  Function ***********************************/

static BOOL mp_subtitle_scale_no_bl(HANDLE osd_dev, UINT16 screen_width)
{
	enum TVSystem tvsys;

    vpo_ioctl((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS), VPO_IO_GET_OUT_MODE, (UINT32)(&tvsys));

    UINT32 param = ap_get_osd_scale_param(tvsys, screen_width);
    OSDDrv_Scale(osd_dev, OSD_SCALE_WITH_PARAM, param);

    return TRUE;
}
#endif


/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_clean_screen
//
// Description:
//	Clear subtitle osd region
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_clean_screen(MpSubtitleOsd *subtitle_osd)
{
	struct OSDRect							r;


	MP_SUB_DEBUG("====>>mp_subtitle_osd_destroy()\n");

	if (!subtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_destroy: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_destroy()\n");
		return;
	}

	r.uLeft = 0;
	r.uTop = 0;
	r.uWidth = MP_SUBTITLE_OSD_WIDTH;
	r.uHeight = MP_SUBTITLE_OSD_HEIGHT;

	OSDDrv_RegionFill((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &r, 16);


}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_change_pallette
//
// Description:
//	Change subtitle osd region pallette
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_change_pallette(MpSubtitleOsd *subtitle_osd, unsigned char* pallette)
{
	MP_SUB_DEBUG("====>>mp_subtitle_osd_change_pallette()\n");

	if ((!subtitle_osd)||(!pallette))
	{
		MP_SUB_DEBUG("mp_subtitle_osd_change_pallette: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_change_pallette()\n");
		return;
	}

	
	OSDDrv_SetPallette((HANDLE)subtitle_osd->osd_dev, pallette, 256, OSDDRV_YCBCR);

	MP_SUB_DEBUG("<<====mp_subtitle_osd_change_pallette()\n");
	return;
}

#ifdef MP_SUBTITLE_SETTING_SUPPORT
/////////////////////////////////////////////////////////////////////////////
//change system data color to subtitle color, according to the subt pallete
//	SUBT_COLOR_BLACK = 0, ==> 0
//	SUBT_COLOR_RED = 1, ==>1
//	SUBT_COLOR_GREEN = 2, ==>2
//	SUBT_COLOR_YELLOW = 3, ==>3
//	SUBT_COLOR_BLUE = 4, ==>4
//	SUBT_COLOR_WHITE = 5, ==>7
//	SUBT_COLOR_TRANSPARENT = 6, ==>16
/////////////////////////////////////////////////////////////////////////////
static INT8 sys_color_2_subt_color(INT8 sys_color)
{
	INT8 subt_color;
	if(SUBT_COLOR_WHITE == sys_color)
		subt_color = 7;
	else if(SUBT_COLOR_TRANSPARENT == sys_color)
		subt_color = 16;
	else
		subt_color = sys_color;

	return subt_color;
}

/////////////////////////////////////////////////////////////////////////////
//change system data y position to subtitle y position
//system data y:0~100
//subtitle data y:-50~50
/////////////////////////////////////////////////////////////////////////////
static INT8 sys_yoffset_2_subt_yoffset(INT8 sys_yoffset)
{
	INT8 subt_yoffset;
	subt_yoffset = 50-sys_yoffset;

	return subt_yoffset;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_string
//
// Description:
//	Draw string on subtitle osd region 
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	x - Offset x
//	y - Offset y
//	fg_color - String color
//	string - String
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_draw_string(MpSubtitleOsd *subtitle_osd, unsigned short x, unsigned short y, unsigned char fg_color, unsigned short *string)
{
	unsigned short					uni_char;
	unsigned short                	uni_char2;
	ID_RSC							resource_id;
	OBJECTINFO						object_info;
	unsigned char					*char_addr;
	unsigned char                 	*char_addr2;
	short							width;
	UINT8                           width2[256];
	short							height;
	long							line_width;
	long							current_height;
	struct OSDRect					r;
	UINT8 i1=0,i2=0; 
	unsigned short 				*stringcopy;
	long							line_total_width[5];
	short							lines=0;
	long							line_start_width=0;
	BOOL     						point_flag=FALSE;

	ID_RSC		RscId;
	RscId=OSD_GetLangEnvironment();		

	long x_offset = 80;//adjust subtitle max width(720 will outside of the screen)
		
#ifdef MP_SUBTITLE_SETTING_SUPPORT
	long							total_height=0;//for string total height
//modify font_size/bg_color/fg_color/y_offset start
	SYSTEM_DATA* sys_data = sys_data_get();
	INT8 font_size;
	INT8 bg_color;
	INT8 y_offset;
	font_size = sys_data->ext_subt_param.font_size;
	fg_color = sys_color_2_subt_color(sys_data->ext_subt_param.fg_color);
	bg_color = sys_color_2_subt_color(sys_data->ext_subt_param.bg_color);
	y_offset = sys_yoffset_2_subt_yoffset(sys_data->ext_subt_param.y_offset);
//modify end
#endif

	#ifdef PERSIAN_SUPPORT
	xformer_capture_semaphore();
    //for persian subtitle 20130618   
    str_cnt =0;
	while(string[str_cnt]&&str_cnt<1023)
	{
		str_keep[str_cnt]=string[str_cnt];
		str_cnt++;
	}
	str_keep[str_cnt]=0x0;
	arabic_unistr_xformer(string,TRUE,FALSE);//handle arabic and persian string	
	xformer_release_semaphore();
	#endif
	stringcopy = string;
	MP_SUB_DEBUG("====>>mp_subtitle_osd_draw_string()\n");

	if ((!subtitle_osd)||(!string))
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_string: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_string()\n");
		return;
	}

	line_width = 0;
	height = 24;
	current_height = 0;

	for(lines=0;lines<5;lines++)
	{
		line_total_width[lines]=0;
	}
	
	lines=0;

	while(*stringcopy)
	{
		uni_char = *stringcopy;
		
		//if (uni_char == L'\n')
		if((uni_char == 0x000D)||(uni_char == 0x000A)||(uni_char == L'|'))//cmx0815	
		{
			if(uni_char == 0x000A||uni_char == L'|')//cmx0815
			{
				lines++;
#ifdef MP_SUBTITLE_SETTING_SUPPORT
				total_height += height;
#endif
				if (lines > 4)
				{
					break;
				}
			}
			stringcopy++;
			continue;
		}
		
		resource_id = OSD_GetDefaultFontLib(uni_char);
#ifdef MP_SUBTITLE_SETTING_SUPPORT
		resource_id |= font_size;
#endif		
		//sutitle_thai start
		UINT32 cnt = 1;
		if (is_thai_unicode(uni_char))
		{
			struct thai_cell cell;
			cnt = thai_get_cell_uni(stringcopy, &cell);
			if(cnt == 0)
			{
				cell.unicode[0]= uni_char;
				cell.char_num = 1;
				cnt = 1;    
			}
			char_addr = (unsigned char*)OSD_GetThaiCellData_ext(resource_id, &cell, &object_info, subtitle_osd->font_buffer);
		}
		else
			//sutitle_thai endif
			char_addr = (unsigned char*)OSD_GetRscObjData_ext(resource_id, uni_char, &object_info, subtitle_osd->font_buffer);	
		if(char_addr == NULL) 
		{
			stringcopy += cnt;//stringcopy++;	//sutitle_thai
			MP_SUB_DEBUG("mp_subtitle_osd_draw_char: We can find this char!\n");
			MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");		
			continue;
		}
#ifdef MP_SUBTITLE_SETTING_SUPPORT
		height = object_info.m_objAttr.m_wHeight;
#endif
		width2[i1]=object_info.m_objAttr.m_wActualWidth;
		line_total_width[lines] += object_info.m_objAttr.m_wActualWidth;
		if(line_total_width[lines]>(MP_SUBTITLE_OSD_WIDTH-x_offset))
		{
			line_total_width[lines] -= object_info.m_objAttr.m_wActualWidth;
			lines++;
#ifdef MP_SUBTITLE_SETTING_SUPPORT
			total_height += height;
#endif
			line_total_width[lines] += object_info.m_objAttr.m_wActualWidth;
		}
		
		stringcopy += cnt;//stringcopy++;	//sutitle_thai
		i1++;
		//if(i1>=256)break;//joey.che
	}
#ifdef MP_SUBTITLE_SETTING_SUPPORT
	total_height += height;
#endif
    //for persian subtitle 20130618 
    #ifdef PERSIAN_SUPPORT
	stringcopy = string;
    #endif
	lines=0;
	while (*string)
	{		
		//uni_char = ComMB16ToUINT16((char*)string);
		uni_char = *string;
		//libc_printf("0x%X\n", uni_char);
		
		//osal_task_sleep(1);
		
		//if (uni_char == L'\n')
		if((uni_char == 0x000D)||(uni_char == 0x000A)||(uni_char == L'|'))//cmx0815	
		{
			if(uni_char == 0x000A||uni_char == L'|')//cmx0815				
			{
				lines++;
				line_width = 0;
				current_height += height;
				if (current_height > 96)
				{
					break;
				}
			}
			string++;
			continue;
		}
		
		resource_id = OSD_GetDefaultFontLib(uni_char);
#ifdef MP_SUBTITLE_SETTING_SUPPORT
		resource_id |= font_size;
#endif
		//sutitle_thai start
		UINT32 cnt = 1;
		if (is_thai_unicode(uni_char))
		{
			struct thai_cell cell;
			cnt = thai_get_cell_uni(string, &cell);
			if(cnt == 0)
			{
				cell.unicode[0]= uni_char;
				cell.char_num = 1;
				cnt = 1;
			}
			char_addr = (unsigned char*)OSD_GetThaiCellData_ext(resource_id, &cell, &object_info, subtitle_osd->font_buffer);
		}
		else
			//sutitle_thai endif
			char_addr = (unsigned char*)OSD_GetRscObjData_ext(resource_id, uni_char, &object_info, subtitle_osd->font_buffer);	
		if(char_addr == NULL) 
		{
			string += cnt;//stringcopy++;	//sutitle_thai
			MP_SUB_DEBUG("mp_subtitle_osd_draw_char: We can find this char!\n");
			MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");		
			continue;
		}

		width = object_info.m_objAttr.m_wActualWidth;
		height = object_info.m_objAttr.m_wHeight;
#ifndef SEVERAL_LANG_SUPPORT
		if(
		   (/*sys_data->lang.OSD_lang*/RscId == PERSIAN_ENV)
		  #if 1//def HEBREW_SUPPORT		//Ben 131127#1
		  || (/*sys_data->lang.OSD_lang*/RscId == ARABIC_ENV)
		  #endif
		  )
		{			
			line_start_width=(MP_SUBTITLE_OSD_WIDTH -(x + line_total_width[current_height/24]))/2+line_total_width[current_height/24];//???			
		}
		else
#endif           
		{
			line_start_width=(MP_SUBTITLE_OSD_WIDTH - line_total_width[lines])/2;
		}

		
		//set mp_subtitle_vscr size
		r.uLeft=line_start_width+line_width;
		//r.uLeft = x + line_width + MP_SUBTITLE_OSD_XOFFSET;
#ifdef MP_SUBTITLE_SETTING_SUPPORT
		r.uTop = MP_SUBTITLE_OSD_HEIGHT - MP_SUBTITLE_OSD_YOFFSET  - total_height + current_height - y_offset;	
#else
		r.uTop = y + current_height + MP_SUBTITLE_OSD_YOFFSET;		
#endif
		r.uWidth = width;
		r.uHeight = height;
#ifndef SEVERAL_LANG_SUPPORT        
		if(
		   (/*sys_data->lang.OSD_lang*/RscId == PERSIAN_ENV)
		  #if 1//def HEBREW_SUPPORT		//Ben 131127#1
		  || (/*sys_data->lang.OSD_lang*/RscId == ARABIC_ENV)
		  #endif
		  )
		{		    
            //for persian subtitle 20130618
		  	//if((width2[i2+1]>1)&&(width2[i2+1]<24))
		  	if((width2[i2+1]>1)&&(width2[i2+1]<48/*24*/))
			{
		      		line_width -= width2[i2+1];
		    	}
			else
			{
				line_width-=20;
			}
			   
			}
		else
#endif           
			line_width += width;
        #ifdef _M3383_SABBAT_
		if (line_width > (MP_SUBTITLE_OSD_WIDTH - 2*x - 50))
        #else
        	//if (line_width > (MP_SUBTITLE_OSD_WIDTH - 2*x))
	 	if (line_width > (MP_SUBTITLE_OSD_WIDTH-x_offset))	
        #endif
		{
			lines++;
			line_width = 0;
			current_height += height;	
			line_start_width = (MP_SUBTITLE_OSD_WIDTH - line_total_width[lines])/2;
			r.uLeft = line_start_width+line_width;
#ifdef MP_SUBTITLE_SETTING_SUPPORT		
			r.uTop = MP_SUBTITLE_OSD_HEIGHT - MP_SUBTITLE_OSD_YOFFSET  - total_height + current_height - y_offset;	
#else
			r.uTop = y + current_height + MP_SUBTITLE_OSD_YOFFSET;
#endif
			line_width += width;
			if (current_height > 96)
			{
				break;
			}
			
		}

#ifdef MP_SUBTITLE_SETTING_SUPPORT
		mp_subtitle_osd_draw_char3(subtitle_osd, char_addr, &object_info, &r, resource_id, fg_color, bg_color);
#else
		mp_subtitle_osd_draw_char2(subtitle_osd, char_addr, &object_info, &r, resource_id, fg_color);
#endif

		string += cnt;//string++;	//sutitle_thai
		i2++;
		if((i2+1)>=256)break;//joey.che		
		//osal_task_sleep(20);
	}

    //for persian subtitle 20130618
    #ifdef PERSIAN_SUPPORT
    string = stringcopy;
    str_cnt =0;
    while(str_keep[str_cnt]&&str_cnt<1023)
    {
        string[str_cnt]=str_keep[str_cnt];
        str_cnt++;
    }
    string[str_cnt]=0x0;
    #endif

	MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_string()\n");
}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_image
//
// Description:
//	Draw image on subtitle osd region 
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	x - Offset x
//	y - Offset y
//	width - Image width
//	height - Image height
//	image - Image
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_draw_image(MpSubtitleOsd *subtitle_osd, unsigned short x, unsigned short y, unsigned short width, unsigned short height,unsigned char *image)
{
	VSCR							mp_subtitle_vscr;
	struct OSDRect					r;

	
	MP_SUB_DEBUG("====>>mp_subtitle_osd_draw_string()\n");

	if ((!subtitle_osd)||(!image))
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_string: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_string()\n");
		return;
	}
	
#ifdef MP_SUBTITLE_SETTING_SUPPORT
//modify y_offset start
	SYSTEM_DATA* sys_data = sys_data_get();
	INT32 y_offset;
	y_offset = sys_yoffset_2_subt_yoffset(sys_data->ext_subt_param.y_offset);	//-50~50 => -100~100
//modify end
#endif

	r.uLeft = x ;
#ifdef MP_SUBTITLE_SETTING_SUPPORT
	r.uTop = MP_SUBTITLE_OSD_HEIGHT - MP_SUBTITLE_OSD_YOFFSET  - height - y_offset;	
#else
	r.uTop = y ;		
#endif
	r.uWidth = width;
	r.uHeight = height;

	
	//MEMSET(image, 1, spu->image_size);

	mp_subtitle_vscr.vR.uLeft = r.uLeft;
	mp_subtitle_vscr.vR.uTop = r.uTop;
	mp_subtitle_vscr.vR.uWidth = r.uWidth;
	mp_subtitle_vscr.vR.uHeight = r.uHeight;
	mp_subtitle_vscr.lpbScr = image;

	// write Vscr data to osd frame buffer
	OSDDrv_RegionWrite((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &mp_subtitle_vscr, &r);
	

}
static UINT8 GetOneBit(const UINT8 *buf, UINT32 pos)
{
    UINT8 clu;
#if 0
    static const UINT8 mask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
#else
    static UINT8 mask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
#endif
    clu = *(buf + (pos >> 3));
    return (clu & mask[pos & 7]);
}

void DrawSubCharMatrix(MpSubtitleOsd *subtitle_osd, UINT32 x, UINT32 y, UINT32 width, UINT32 height, const UINT8 *ptr, UINT32 stride, UINT32 bg, UINT32 fg)
{
    UINT32 i, j;
    UINT32 x0;
    UINT32 actual_width = (width >> 16) & 0xFFFF;
    width &= 0xFFFF;
    if(!actual_width || actual_width > width)
        actual_width = width;

    UINT32 pos = stride >> 16;
    stride &= 0xffff;
    
    for(i = 0; i < height; i++, y++)
    {
        x0 = x;
        if (stride)
            pos = 0;
        UINT32 one_bit;
        UINT32 next_bit = GetOneBit(ptr, pos++);
        j = 0;
        while (j < actual_width)
        {
            one_bit = next_bit;
            UINT32 num = 0;
#if 1
            do
            {
                num++;
                j++;
                if (j >= actual_width)
                    break;
                next_bit = GetOneBit(ptr, pos++);
            } while (next_bit == one_bit);
#else
            pos--;
            for(; j < width; j++, num++)
            {
                next_bit = GetOneBit(ptr, pos++);
                if (next_bit != one_bit)
                    break;
            }
#endif
            if (one_bit)
            {
				OSDDrv_DrawHorLine((HANDLE)subtitle_osd->osd_dev, (UINT8)subtitle_osd->region, x0, y, num, fg);
            }
            else
            {
                if ((bg & C_MIXER) == 0)
		    	{
			 	OSDDrv_DrawHorLine((HANDLE)subtitle_osd->osd_dev, (UINT8)subtitle_osd->region, x0, y, num,bg);
		    	}
            }
            x0 += num;
        }
        pos += (width - actual_width);
        ptr += stride;
    }
}

/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_get_rects_cross
//
// Description:
//	Borrowed from osd library. Thank you, Xian_Zhou
//
// Arguments:
//	?
//	
// Return Value:
//	1 - Success
//	0 - Failed
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_get_rects_cross(const struct OSDRect *backR,const struct OSDRect *forgR, struct OSDRect* relativR)
{
	short ltx,lty,rbx,rby;
	short dw,dh;

	ltx = forgR->uLeft >=  backR->uLeft ? forgR->uLeft :  backR->uLeft;
	lty = forgR->uTop >=  backR->uTop ? forgR->uTop :  backR->uTop;
	rbx = (forgR->uLeft + forgR->uWidth) <= (backR->uLeft + backR->uWidth) ? (forgR->uLeft + forgR->uWidth) : (backR->uLeft + backR->uWidth);
	rby = (forgR->uTop + forgR->uHeight) <= (backR->uTop + backR->uHeight) ? (forgR->uTop + forgR->uHeight) : (backR->uTop + backR->uHeight);

	dw = rbx > ltx ? (rbx - ltx) : 0;
	dh = rby > lty ? (rby - lty) : 0;
	relativR->uWidth  = dw;
	relativR->uHeight = dh;
	relativR->uLeft = ltx;
  	relativR->uTop  = lty;	
}

/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_bitmap_format_transfer
//
// Description:
//	Borrowed from osd library. Thank you, Xian_Zhou
//
// Arguments:
//	?
//	
// Return Value:
//	1 - Success
//	0 - Failed
//
/////////////////////////////////////////////////////////////////////////////
static BOOL mp_subtitle_osd_bitmap_format_transfer(BitMap_t* bmpDest,BitMap_t* bmpSrc,UINT32 transColor,UINT32 foreColor)
{
	struct OSDRect destRect,srcRect,crossRect;
	UINT16 i,j;
	UINT8 maskDest,maskSrc;
	UINT8 backByte,foreByte,foreBits;
	UINT8 fBytePixOffset,bBytePixOffset;
	UINT8 pixsPerByteDest,pixsPerByteSrc;
	UINT32 fLineStartPixsOffset,bLineStartPixsOffset,bLineByteOffset;
	
	UINT8	*pForgLineData,*pBackLineData;
	UINT8	*pFgColor;
	BOOL	bMix;
	UINT8 bTransColor = transColor;
	UINT8 bTransColorTmp = transColor;
	UINT8 bForeColor = foreColor;

	// If data bitmap data is null, return 
	if((bmpSrc->pData==NULL) || (bmpDest->pData == NULL))
		return FALSE;

	//if(bmpSrc->bitsPerPix < bmpDest->bitsPerPix)
	//	bTransColor =0;
	destRect.uLeft   = bmpDest->uLeft;
	destRect.uTop    = bmpDest->uTop;
	destRect.uWidth  = bmpDest->uWidth;
	destRect.uHeight = bmpDest->uHeight;

	srcRect.uLeft   = bmpSrc->uLeft;
	srcRect.uTop    = bmpSrc->uTop;
	srcRect.uWidth  = bmpSrc->uWidth;
	srcRect.uHeight = bmpSrc->uHeight;

	// Get the cross rectangle of source and dest bitmap. 
	mp_subtitle_osd_get_rects_cross(&destRect,&srcRect,&crossRect);

	// If the cross rectange is emplty return. 
	if((crossRect.uWidth*crossRect.uHeight)==0)
		return FALSE;

	maskDest = (2<<bmpDest->bitsPerPix - 1) - 1;
	maskSrc = (2<<bmpSrc->bitsPerPix- 1) - 1;
	
	bTransColor &= maskSrc;
	bForeColor  &= maskDest;

	//* If tansparenct color is not same with forground color, the mixing is ture,
	//   else not mixing. 
	if(bmpSrc->bitsPerPix < bmpDest->bitsPerPix)
	{
		bTransColor =0;
		if(bTransColorTmp!=bForeColor)
		bMix = TRUE;
		else
		bMix = FALSE;
	}
	else
	{
		if(bTransColor!=bForeColor)// || maskSrc==0xFF)
		bMix = TRUE;
		else
		bMix = FALSE;		
	}

	// pixs per byte 
	pixsPerByteDest = 8 / bmpDest->bitsPerPix;
	pixsPerByteSrc  = 8 / bmpSrc->bitsPerPix;

	// The dest copy data area every line's start pix index in the first byte. 
	bLineStartPixsOffset = crossRect.uLeft % pixsPerByteDest;
	fLineStartPixsOffset = (crossRect.uLeft - srcRect.uLeft)% pixsPerByteSrc;

	// Decide what data are copyed to the dest bitmap 
	if(bmpSrc->bitsPerPix < bmpDest->bitsPerPix)
	{
		pFgColor = &bForeColor;	// 1bit per pix -- font data 

		if( NULL != bmpDest->pData)
		{
			pBackLineData = bmpDest->pData + (crossRect.uLeft-destRect.uLeft) *  bmpDest->bitsPerPix / 8
							+bmpDest->stride * (crossRect.uTop - destRect.uTop); 
			pForgLineData = bmpSrc->pData+ (crossRect.uLeft-srcRect.uLeft) * bmpSrc->bitsPerPix / 8
							+ bmpSrc->stride * (crossRect.uTop - srcRect.uTop);
			for(i=0;i<crossRect.uHeight;i++)	// every line 
			{
				for(j=0;j<crossRect.uWidth;j++)	// every pix 
				{									
					foreByte = *(pForgLineData + (fLineStartPixsOffset + j) / pixsPerByteSrc) ;	//Foreground byte of pix j from fLineStartPixsOffset /
			    		fBytePixOffset = (pixsPerByteSrc - 1 - (fLineStartPixsOffset + j) % pixsPerByteSrc) * bmpSrc->bitsPerPix;				// Foreground pix of j from fLineStartPixsOffset's data offset in the foreByte /
					foreBits = (foreByte >> fBytePixOffset) & maskSrc ;
					
					*(pBackLineData +j) = bTransColorTmp;//16;
					
					if(!bMix ||  foreBits != bTransColor)
					{
						bLineByteOffset = (bLineStartPixsOffset + j)/pixsPerByteDest;
													
						bBytePixOffset = (pixsPerByteDest - 1 - (bLineStartPixsOffset + j) % pixsPerByteDest) * bmpDest->bitsPerPix;			// Background pix of j from fLineStartPixsOffset's data offset in the backByte /
						backByte = *( pBackLineData + bLineByteOffset );								// Background byte of pix j from bLineStartPixsOffset /

						backByte &= ~(maskDest<<bBytePixOffset);

						backByte |= *pFgColor << bBytePixOffset;
						*(pBackLineData + bLineByteOffset) = backByte;
					}	

				}
				pBackLineData += bmpDest->stride;
				pForgLineData += bmpSrc->stride;
			}
		}
	}
	else
	{
		pFgColor = &foreBits;	// icon data 
		

	//pback = bmpDest->pData ;	
	//pfore = bmpSrc->pData;
	if( NULL != bmpDest->pData)
	{
		pBackLineData = bmpDest->pData + (crossRect.uLeft-destRect.uLeft) *  bmpDest->bitsPerPix / 8
						+bmpDest->stride * (crossRect.uTop - destRect.uTop); 
		pForgLineData = bmpSrc->pData+ (crossRect.uLeft-srcRect.uLeft) * bmpSrc->bitsPerPix / 8
						+ bmpSrc->stride * (crossRect.uTop - srcRect.uTop);
		for(i=0;i<crossRect.uHeight;i++)	// every line 
		{
			for(j=0;j<crossRect.uWidth;j++)	// every pix 
			{
				if(maskDest == maskSrc && maskDest==0xFF)
				{
					foreByte = *(pForgLineData + fLineStartPixsOffset + j);
					if(!bMix ||  foreByte != bTransColor)
						*( pBackLineData + bLineStartPixsOffset + j ) = foreByte;
					
					continue;
				}

			
				foreByte = *(pForgLineData + (fLineStartPixsOffset + j) / pixsPerByteSrc) ;	//Foreground byte of pix j from fLineStartPixsOffset /
		    		fBytePixOffset = (pixsPerByteSrc - 1 - (fLineStartPixsOffset + j) % pixsPerByteSrc) * bmpSrc->bitsPerPix;				// Foreground pix of j from fLineStartPixsOffset's data offset in the foreByte /
				foreBits = (foreByte >> fBytePixOffset) & maskSrc ;
					
				if(!bMix ||  foreBits != bTransColor)
				{
					bLineByteOffset = (bLineStartPixsOffset + j)/pixsPerByteDest;
												
					bBytePixOffset = (pixsPerByteDest - 1 - (bLineStartPixsOffset + j) % pixsPerByteDest) * bmpDest->bitsPerPix;			// Background pix of j from fLineStartPixsOffset's data offset in the backByte /
					backByte = *( pBackLineData + bLineByteOffset );								// Background byte of pix j from bLineStartPixsOffset /

					backByte &= ~(maskDest<<bBytePixOffset);

					backByte |= *pFgColor << bBytePixOffset;
					*(pBackLineData + bLineByteOffset) = backByte;
				}	

				}
				pBackLineData += bmpDest->stride;
				pForgLineData += bmpSrc->stride;
			}
		}
	}
	
	return TRUE;
		
}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_icon_char_data2bitmap
//
// Description:
//	Borrowed from osd library. Thank you, Xian_Zhou
//
// Arguments:
//	?
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_icon_char_data2bitmap(FONTICONPROP* pObjAttr,UINT8* pDtaBitmap,BitMap_t* bmp, ID_RSC RscLibId)
{

	bmp->uWidth  = pObjAttr->m_wActualWidth;//RscLibInfo.m_objAttr.m_wActualWidth
	bmp->uHeight = pObjAttr->m_wHeight;

	if(LIB_FONT == (RscLibId&0xF000))
	{
		if( LIB_FONT_MASSCHAR == (RscLibId&0xFF00))
			bmp->stride = pObjAttr->m_wWidth;
		else
			bmp->stride = pObjAttr->m_wWidth*pObjAttr->m_bColor/8;
	}
	else
		bmp->stride = pObjAttr->m_wWidth;

	bmp->pData   = pDtaBitmap;
	bmp->bitsPerPix = pObjAttr->m_bColor;
}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_bmp
//
// Description:
//	Borrowed from osd library. Thank you, Xian_Zhou
//
// Arguments:
//	?
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
//static void mp_subtitle_osd_draw_bmp(UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag)
static void mp_subtitle_osd_draw_bmp(MpSubtitleOsd *subtitle_osd, UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag)
{
	UINT32 		bTransColor,bForgColor;
	BitMap_t	destBmp,srcBmp;

	if((NULL == pbVscr) || (NULL == pbVscr->lpbScr))
		return;

	bForgColor	= GET_COLOR_IDX(dwColorFlag);
	srcBmp.uLeft = r->uLeft;
	srcBmp.uTop  = r->uTop;
	mp_subtitle_osd_icon_char_data2bitmap(&RscLibInfo->m_objAttr,pDtaBitmap,&srcBmp, RscLibId);
	srcBmp.uWidth = r->uWidth > srcBmp.uWidth ? srcBmp.uWidth : r->uWidth;
	srcBmp.uHeight = r->uHeight > srcBmp.uHeight ? srcBmp.uHeight : r->uHeight;
	
	#if 0
	bTransColor = 0;
	destBmp.uLeft	= pbVscr->vR.uLeft;
	destBmp.uTop	= pbVscr->vR.uTop;
	destBmp.uWidth 	= pbVscr->vR.uWidth;
	destBmp.uHeight = pbVscr->vR.uHeight;
	destBmp.pData 	= pbVscr->lpbScr;
	destBmp.stride	= OSD_GET_VSCR_STIDE(pbVscr);
	destBmp.bitsPerPix = BIT_PER_PIXEL;
	
	mp_subtitle_osd_bitmap_format_transfer(&destBmp,&srcBmp,bTransColor,bForgColor);
	#else
	bTransColor = 255;
	//libc_printf("srcBmp.uLeft=%d,srcBmp.uTop=%d,srcBmp.uWidth=%d,srcBmp.uHeight=%d\n",srcBmp.uLeft,srcBmp.uTop,srcBmp.uWidth,srcBmp.uHeight);
	DrawSubCharMatrix(subtitle_osd, srcBmp.uLeft, srcBmp.uTop, srcBmp.uWidth, srcBmp.uHeight, srcBmp.pData, srcBmp.stride, bTransColor, bForgColor);
	#endif
}

#ifdef MP_SUBTITLE_SETTING_SUPPORT
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_bmp3
//
// Description:
//	Borrowed from osd library. Thank you, Xian_Zhou
//
// Arguments:
//	?
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
//static void mp_subtitle_osd_draw_bmp(UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag)
static void mp_subtitle_osd_draw_bmp3(MpSubtitleOsd *subtitle_osd, UINT8 *pDtaBitmap,OBJECTINFO*	RscLibInfo, lpVSCR pbVscr, struct OSDRect* r, ID_RSC RscLibId,UINT32 dwColorFlag, UINT32 dwBgColorFlag)
{
	UINT32 		bTransColor,bForgColor;
	BitMap_t	destBmp,srcBmp;

	if((NULL == pbVscr) || (NULL == pbVscr->lpbScr))
		return;

	bForgColor	= GET_COLOR_IDX(dwColorFlag);
	srcBmp.uLeft = r->uLeft;
	srcBmp.uTop  = r->uTop;
	mp_subtitle_osd_icon_char_data2bitmap(&RscLibInfo->m_objAttr,pDtaBitmap,&srcBmp, RscLibId);
	srcBmp.uWidth = r->uWidth > srcBmp.uWidth ? srcBmp.uWidth : r->uWidth;
	srcBmp.uHeight = r->uHeight > srcBmp.uHeight ? srcBmp.uHeight : r->uHeight;
	
	#if 1
	bTransColor = dwBgColorFlag;//0;
	destBmp.uLeft	= pbVscr->vR.uLeft;
	destBmp.uTop	= pbVscr->vR.uTop;
	destBmp.uWidth 	= pbVscr->vR.uWidth;
	destBmp.uHeight = pbVscr->vR.uHeight;
	destBmp.pData 	= pbVscr->lpbScr;
	destBmp.stride	= OSD_GET_VSCR_STIDE(pbVscr);
	destBmp.bitsPerPix = BIT_PER_PIXEL;
	
	mp_subtitle_osd_bitmap_format_transfer(&destBmp,&srcBmp,bTransColor,bForgColor);
	#else
	bTransColor = dwBgColorFlag;
	//libc_printf("srcBmp.uLeft=%d,srcBmp.uTop=%d,srcBmp.uWidth=%d,srcBmp.uHeight=%d\n",srcBmp.uLeft,srcBmp.uTop,srcBmp.uWidth,srcBmp.uHeight);
	DrawSubCharMatrix(subtitle_osd, srcBmp.uLeft, srcBmp.uTop, srcBmp.uWidth, srcBmp.uHeight, srcBmp.pData, srcBmp.stride, bTransColor, bForgColor);
	#endif
}
#endif

/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_char
//
// Description:
//	Draw char on subtitle osd region, for debug
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	x - Offset x
//	y - Offset y
//	width - Char width
//	height - Char height
//	character - Char
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_draw_char(MpSubtitleOsd *subtitle_osd, unsigned short x, unsigned short y, unsigned char fg_color, unsigned short character)
{
	unsigned char						*pData; 
	struct OSDRect					r;
	short							width,height;
	unsigned char						charset_idx, char_idx;
	unsigned long						charmask;
	unsigned short					bit_count;
	unsigned char						i, j, k;
	unsigned char						data1, data2;
	unsigned char						zoomkind;
	unsigned char						temp;
	unsigned char						*char_addr;
	VSCR							mp_subtitle_vscr;
	ID_RSC							resource_id;
	OBJECTINFO						object_info;

	


	MP_SUB_DEBUG("====>>mp_subtitle_osd_draw_char()\n");

	if (!subtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_char: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
		return;
	}
/*	
	if((x%MP_SUBTITLE_OSD_CHAR_W) != 0 || (y%MP_SUBTITLE_OSD_CHAR_H) != 0 || x+MP_SUBTITLE_OSD_CHAR_W > MP_SUBTITLE_OSD_WIDTH)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_char: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
		return ;
	}

	if(y+MP_SUBTITLE_OSD_CHAR_H > MP_SUBTITLE_OSD_HEIGHT)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_char: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
		return;
	}
*/

	//character = ComMB16ToUINT16((char*)(&character));
	resource_id = OSD_GetDefaultFontLib(character);
	char_addr = (unsigned char*)OSD_GetRscObjData(resource_id, character, &object_info);	
	if(char_addr == NULL) 
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_char: We can find this char!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");		
		return;
	}
	
	width = object_info.m_objAttr.m_wActualWidth;
	height = object_info.m_objAttr.m_wHeight;

	//set mp_subtitle_vscr size
	r.uLeft = x + MP_SUBTITLE_OSD_XOFFSET;
	r.uTop = y + MP_SUBTITLE_OSD_YOFFSET;
	r.uWidth = width;
	r.uHeight = height;

	mp_subtitle_vscr.vR.uLeft = r.uLeft;
	mp_subtitle_vscr.vR.uTop = r.uTop;
	mp_subtitle_vscr.vR.uWidth = width;
	mp_subtitle_vscr.vR.uHeight = height;
	mp_subtitle_vscr.lpbScr = subtitle_osd->vscr_buffer;

	//mp_subtitle_osd_draw_bmp(char_addr, &object_info, &mp_subtitle_vscr, &r, resource_id, fg_color);
	mp_subtitle_osd_draw_bmp(subtitle_osd, char_addr, &object_info, &mp_subtitle_vscr, &r, resource_id, fg_color);

	// write Vscr data to osd frame buffer
	OSDDrv_RegionWrite((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &mp_subtitle_vscr, &r);

	MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
}
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_char2
//
// Description:
//	Draw char on subtitle osd region
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	char_addr - Bitmap of the char
//	object_info - ?
//	r - Pointer to struct OSDRect
//	resource_id - Resource in project's resource folder
//	fg_color - Color of the char
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_draw_char2(MpSubtitleOsd *subtitle_osd, unsigned char *char_addr,OBJECTINFO *object_info, struct OSDRect *r, ID_RSC resource_id, unsigned char fg_color)
{
	VSCR							mp_subtitle_vscr;
	
	MP_SUB_DEBUG("====>>mp_subtitle_osd_draw_char()\n");

	if (!subtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_char: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
		return;
	}

	mp_subtitle_vscr.vR.uLeft = r->uLeft;
	mp_subtitle_vscr.vR.uTop = r->uTop;
	mp_subtitle_vscr.vR.uWidth = r->uWidth;
	mp_subtitle_vscr.vR.uHeight = r->uHeight;
	mp_subtitle_vscr.bColorMode = OSD_256_COLOR;
	mp_subtitle_vscr.lpbScr = subtitle_osd->vscr_buffer;
	MEMSET(subtitle_osd->vscr_buffer, 0 , 100*100);

	//mp_subtitle_osd_draw_bmp(char_addr, object_info, &mp_subtitle_vscr, r, resource_id, fg_color);
	mp_subtitle_osd_draw_bmp(subtitle_osd, char_addr, object_info, &mp_subtitle_vscr, r, resource_id, fg_color);

	// write Vscr data to osd frame buffer
	//OSDDrv_RegionWrite((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &mp_subtitle_vscr, r);

	MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
}

#ifdef MP_SUBTITLE_SETTING_SUPPORT
/////////////////////////////////////////////////////////////////////////////
// mp_subtitle_osd_draw_char3
//
// Description:
//	Draw char on subtitle osd region
//
// Arguments:
//	subtitle_osd - Pointer to a struct contains osd infomation
//	char_addr - Bitmap of the char
//	object_info - ?
//	r - Pointer to struct OSDRect
//	resource_id - Resource in project's resource folder
//	fg_color - Color of the char
//	bg_color - Color of background
//	
// Return Value:
//	None
//
/////////////////////////////////////////////////////////////////////////////
static void mp_subtitle_osd_draw_char3(MpSubtitleOsd *subtitle_osd, unsigned char *char_addr,OBJECTINFO *object_info, struct OSDRect *r, ID_RSC resource_id, unsigned char fg_color, unsigned char bg_color)
{
	VSCR							mp_subtitle_vscr;
	
	MP_SUB_DEBUG("====>>mp_subtitle_osd_draw_char()\n");

	if (!subtitle_osd)
	{
		MP_SUB_DEBUG("mp_subtitle_osd_draw_char: Invalid Parameters!\n");
		MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
		return;
	}

	mp_subtitle_vscr.vR.uLeft = r->uLeft;
	mp_subtitle_vscr.vR.uTop = r->uTop;
	mp_subtitle_vscr.vR.uWidth = r->uWidth;
	mp_subtitle_vscr.vR.uHeight = r->uHeight;
	mp_subtitle_vscr.bColorMode = OSD_256_COLOR;
	mp_subtitle_vscr.lpbScr = subtitle_osd->vscr_buffer;
	MEMSET(subtitle_osd->vscr_buffer, 0 , 100*100);

	//mp_subtitle_osd_draw_bmp(char_addr, object_info, &mp_subtitle_vscr, r, resource_id, fg_color);
	mp_subtitle_osd_draw_bmp3(subtitle_osd, char_addr, object_info, &mp_subtitle_vscr, r, resource_id, fg_color, bg_color);

	// write Vscr data to osd frame buffer
	OSDDrv_RegionWrite((HANDLE)subtitle_osd->osd_dev, subtitle_osd->region, &mp_subtitle_vscr, r);

	MP_SUB_DEBUG("<<====mp_subtitle_osd_draw_char()\n");
}
#endif

